package com.sxhuayuan.parking.controller.member;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.sxhuayuan.parking.compenent.Message;
import com.sxhuayuan.parking.compenent.web.RespMessage;
import com.sxhuayuan.parking.compenent.web.RespMessage.Status;
import com.sxhuayuan.parking.config.PayMode;
import com.sxhuayuan.parking.config.Platform;
import com.sxhuayuan.parking.dto.CreateMcardChargeOrderDTO;
import com.sxhuayuan.parking.dto.QueryMcardDTO;
import com.sxhuayuan.parking.entity.Member;
import com.sxhuayuan.parking.entity.MemberCarPlate;
import com.sxhuayuan.parking.entity.MonthCardOrder;
import com.sxhuayuan.parking.entity.ParkingLot;
import com.sxhuayuan.parking.exception.MyException;
import com.sxhuayuan.parking.plugin.parking.ParkingPlugin;
import com.sxhuayuan.parking.plugin.parking.bean.McardChargeOption;
import com.sxhuayuan.parking.plugin.parking.result.McardChargeOrderCreateResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardQueryChargeOptionsResultWrap;
import com.sxhuayuan.parking.plugin.parking.result.McardQueryResultWrap;
import com.sxhuayuan.parking.plugin.payment.ResultPayJsonData;
import com.sxhuayuan.parking.plugin.payment.WxPayPlugin;
import com.sxhuayuan.parking.service.MemberCarPlateService;
import com.sxhuayuan.parking.service.MemberService;
import com.sxhuayuan.parking.service.MonthCardOrderService;
import com.sxhuayuan.parking.service.ParkingLotService;
import com.sxhuayuan.parking.service.PluginService;
import com.sxhuayuan.parking.utils.DeviceUtil;

@Controller("memberMcardController")
@RequestMapping("/member/mcard")
public class McardController extends BaseController {

	@Resource(name = "monthCardOrderServiceImpl")
	MonthCardOrderService service;
	@Resource(name = "parkingLotServiceImpl")
	ParkingLotService lotService;
	@Resource(name = "pluginServiceImpl")
	PluginService pluginService;

	@Resource(name = "memberCarPlateServiceImpl")
	MemberCarPlateService carPlateService;

	@Resource(name = "memberServiceImpl")
	MemberService memberService;

	@Resource(name = "wxPayPlugin")
	WxPayPlugin wxpayPlugin;

	Logger log = LoggerFactory.getLogger(getClass());

	private final String SESSION_ATTR_CHARGE_ORDER = "chargeOrder";

	/**
	 * 月卡缴费页面
	 */
	@RequestMapping(value = "/charge", method = RequestMethod.GET)
	public String mcardCashier() {
		return "monthcard/monthcard";
	}

	/** 查询车辆月卡信息 */
	@RequestMapping(value = "/getinfo", method = RequestMethod.POST)
	@ResponseBody
	public RespMessage getInfo(@Validated @RequestBody QueryMcardDTO dto) {
		ParkingLot parkingLot = lotService.findBySn(getLotSnFromSession());
		if (Objects.isNull(parkingLot)) {
			return RespMessage.error(Status.VALID_ERR, Message.PARKING_LOT_NOT_EXISTS);
		}
		ParkingPlugin plugin = pluginService.getParkingPlugin(parkingLot.getPluginId());
		MemberCarPlate carPlate = carPlateService.findOne(dto.getCarPlateId());
		try {
			McardQueryResultWrap monthCardQuery = plugin.monthCardQuery(getLotSnFromSession(), carPlate);
			return RespMessage.builder().success().setDatas(monthCardQuery).build();
		} catch (Exception e) {
			log.error("", e);
			throw new MyException(Status.ERROR, Message.COMMON_NETWORK_ERR);

		}
	}

	/** 查询当前用户所有车辆月卡信息 */
	@RequestMapping(value = "/getinfos", method = RequestMethod.POST)
	@ResponseBody
	public RespMessage getAllCarPlateMonthCardInfos() {
		ParkingLot parkingLot = lotService.findBySn(getLotSnFromSession());
		ParkingPlugin plugin = pluginService.getParkingPlugin(parkingLot.getPluginId());
		List<MemberCarPlate> allCarPlates = carPlateService.findList(memberService.getCurrent().getId());
		try {
			List<McardQueryResultWrap> datas = new ArrayList<>(allCarPlates.size());
			for (MemberCarPlate cp : allCarPlates) {
				datas.add(plugin.monthCardQuery(getLotSnFromSession(), cp));
			}
			return RespMessage.builder().success().setDatas(datas).build();
		} catch (Exception e) {
			log.error("", e);
			throw new MyException(Status.ERROR, Message.COMMON_NETWORK_ERR);

		}
	}

	/** 查询月卡缴费选项 */
	@RequestMapping(value = "/chargeoptions")
	@ResponseBody
	public RespMessage chargeOptions() {
		ParkingLot parkingLot = lotService.findBySn(getLotSnFromSession());
		ParkingPlugin plugin = pluginService.getParkingPlugin(parkingLot.getPluginId());
		McardQueryChargeOptionsResultWrap resultWrap = plugin.monthCardQueryChargeOptions(parkingLot.getSn());
		if (resultWrap.getIsSuccess()) {
			return RespMessage.builder().success().setDatas(resultWrap.getOptions()).build();
		} else {
			return RespMessage.error(resultWrap.getMsg());
		}
	}

	/**
	 * 创建缴费订单接口
	 * 
	 * @param dto
	 * @param request
	 * @param session
	 * @return
	 */
	@RequestMapping("/createorder")
	@ResponseBody
	public RespMessage createOrder(@Validated @RequestBody CreateMcardChargeOrderDTO dto, HttpServletRequest request) {
		ParkingLot lot = lotService.findBySn(dto.getLotSn());
		if (Objects.isNull(lot)) {
			return RespMessage.error(Status.VALID_ERR, Message.PARKING_LOT_NOT_EXISTS);
		}
		MemberCarPlate carPlate = carPlateService.findOne(dto.getCarPlateId());
		if (carPlate == null) {
			return RespMessage.error(Message.CAR_PLATE_ERR);
		}
		Member current = memberService.getCurrent();
		if (!current.equals(carPlate.getMember())) {
			return RespMessage.error(Message.CAR_PLATE_ERR);
		}
		Platform platform = getPlatform(request);
		ParkingPlugin plugin = pluginService.getParkingPlugin(lot.getPluginId());
		HttpSession session = request.getSession();
		if (StringUtils.isEmpty(dto.getLotOrderSn())) {
			// 调用车场接口下单，但支付先不下单，因为要返回给用户确认月卡费用和到期时间，确认后再支付下单
			McardChargeOrderCreateResultWrap resultWrap = plugin.monthCardCreateOrder(carPlate, dto, platform);
			if (resultWrap.getIsSuccess()) {
				session.setAttribute(SESSION_ATTR_CHARGE_ORDER, resultWrap);
				return RespMessage.builder().success().setDatas(resultWrap).build();
			}
			return RespMessage.builder().error().setErr(resultWrap.getMsg()).build();
		} else {
			// 确认下单
			Object obj = session.getAttribute(SESSION_ATTR_CHARGE_ORDER);
			if (obj == null || !(obj instanceof McardChargeOrderCreateResultWrap)) {
				return RespMessage.error("订单过期，请重新下单");
			}
			McardChargeOrderCreateResultWrap resultWrap = (McardChargeOrderCreateResultWrap) obj;
			if (!StringUtils.equals(dto.getLotOrderSn(), resultWrap.getLotOrderNo())) {
				return RespMessage.error("订单过期，请重新下单");
			}
			String ip = DeviceUtil.getRemortIP(request);
			McardChargeOption option = plugin.getMonthCardChargeOptionsMap(lot.getSn()).get(dto.getTariffId());
			try {
				MonthCardOrder order = service.createMonthCardOrder(carPlate, lot, new BigDecimal(dto.getMoney()), plugin.getId(), platform, PayMode.jssdk, ip, dto.getRemark(),
						dto.getMonthNum(), option, dto.getCurrExpireDate(), dto.getPreExpireDate());
				ResultPayJsonData payJsonData = null;
				payJsonData = wxpayPlugin.unified(order);
				return RespMessage.builder().success().setDatas(payJsonData).build();
			} catch (Exception e) {
				log.error("", e);
				return RespMessage.error(Status.ERROR, "下单失败：" + e.getMessage());
			}
		}
	}
}
